
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QComboBox>
#include <QCompleter>
#include <QDebug>
#include <QDesktopWidget>
#include <QMovie>
#include <QPixmap>
#include <QRect>
#include <QTimer>
#include <QPropertyAnimation>
#include <screenutil.h>

#ifdef ZTBOX_BUILTIN_PLUGINS
#include <plugins/builtin/helloworld/helloextension.h>
#include <plugins/builtin/other/settingsextension.h>
#include <plugins/builtin/version/versionextension.h>
#include <uianalyzerplugin.h>
#include <apthistory.h>
#include <windowposplugin.h>
#endif

void MainWindow::showWidget(QWidget *widget)
{
    auto w = widget->width();
    auto h = widget->height();
    {   // fix widget min size
//        if (widget != emptyWidget)
//        if (widget->minimumSize() == QSize(0, 0)) {
//            const auto fixed_size = QSize(600, 400);
//            widget->setMinimumSize(fixed_size);
//            widget->resize(fixed_size);
//        }
    }
//    qDebug() << widget->minimumSize();
    auto s = widget->minimumSize() + QSize(2, 7 + ui->frame->height()); // +60 为在原始程序的高度基础上

    // 当添加到 VBoxLayout 布局中时，即可调整窗口大小
    ui->centralwidget->layout()->addWidget(widget);
    widget->show();

    animation->setEndValue(s);
//    if (s.width() > this->size().width()) {
//        showDesktopTopCenter(widget);
//        connect(animation, &QPropertyAnimation::finished, [=](){
//            showDesktopTopCenter();
//        });
//    }
    animation->start();
}

bool MainWindow::compareExtensions(ZTBoxInterface *extension)
{
    auto comboText = this->ui->toolslist->currentText().toLower();
    auto extensText = extension->PluginName().toLower();
    return comboText.compare(extensText) == 0;
}

void MainWindow::initPluginCompleter()
{
    // 从 Builtin 中取出可用项
    QStringList builtlist;
    foreach (auto widget, listWidgets) {
        builtlist << widget->PluginName();
    }

    // 自动补全提供者
    QCompleter *comp = new QCompleter(builtlist);
    comp->setCaseSensitivity(Qt::CaseInsensitive);
    ui->toolslist->clear();
    ui->toolslist->addItems(builtlist);
    ui->toolslist->setCompleter(comp);
    
    animationHolder->setTextList(builtlist);
}

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , currentExtension(nullptr)
    , animation(new QPropertyAnimation(this, "size", this))
    , emptyWidget(new QWidget)
{
    ui->setupUi(this);

    ui->icon->showMovieIcon();
    animation->setDuration(200);

    animationHolder = new AnimationText(ui->toolslist);

    // 使用定时器检查窗口是否为被激活窗口
    QTimer *timerCheck = new QTimer();
    timerCheck->setInterval(1000);
    timerCheck->start();
    connect(timerCheck, &QTimer::timeout, [=](){
        qDebug() << __FUNCTION__ << "isActiveWindow:" << this->isActiveWindow();

        // 当未激活窗口并且当前扩展部件未明确表示持续显示时将关闭当前窗口
        if (!this->isActiveWindow() && (!currentExtension || !currentExtension->PluginxAlwaysDisplay())) {
            this->close(); // 在检查到未激活窗口时关闭
        }
    });


    /**
     * @brief  在[输入]变化时触发选中
     * @note    [严谨的逻辑设计]
     * @param  &s:
     * @retval
     */
    connect(ui->toolslist, &QComboBox::currentTextChanged, this , [=](const QString &s){
        qDebug() << __FUNCTION__ << "currentTextChanged:" << s;
        ui->icon->showMovieIcon();

        // [细节]记录本次可能遇到到可预览的扩展
        ZTBoxInterface *preview = nullptr;

        foreach (auto widget, listWidgets) {
            
            // [细节]跳过没有初始化的延时加载控件
            if (!widget->pluginAutoLoader() && widget->taskState() != ZTBoxInterface::Initialized) {
                continue;
            }

            // [细节]跳过不属于该窗口的控件
            if (!widget->pluginWidget()->parentWidget()) {
                continue;
            }

            // 当前未匹配时，准备隐藏所有控件
            if (!compareExtensions(widget)) {
                qDebug() << __FUNCTION__ << "foreach[hide]:" <<  widget->PluginName();

                // 隐藏该控件
                widget->pluginWidget()->hide();
                // widget->pluginWidget()->setParent(nullptr);

                // 如果是先前激活的控件
                if (currentExtension == widget) {
                    // 在切换时可能需要调整位置
                    if (currentExtension->pluginShowResetPosistion()) {
//                        showDesktopTopCenter(widget->pluginWidget());
                    }

                    // 先前激活的控件将置空
                    currentExtension = nullptr;
                }
                // resize(0,0);
                animation->setStartValue(this->size());
            } else {
                qDebug() << __FUNCTION__ << "foreach[show]:" <<  widget->PluginName();
                preview = widget;
            }
        }
        
        // [细节] 可实时显示可用面板
        if (preview) {
            // [细节] 支持未触发 currentIndexChanged 导致无法使用双击隐藏面板
            currentExtension = preview;

            // [细节] 所有扩展都使用 pluginWidget() 来获取实例
            showWidget(preview->pluginWidget());
        } else {
            showWidget(emptyWidget);
        }
    });

    /**
     * @brief  在[回车]选中项时触发选中
     * @note    [严谨的逻辑设计]
     * @param  (QComboBox::*: 
     * @retval 
     */
    connect(ui->toolslist, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this , [=](int index){
        qDebug() << __FUNCTION__ << "currentIndexChanged:" << index;
        // 处理可能越界的异常
        if (index == -1) return;
        if (listWidgets.size() <= index) return;

        // 处理可能不匹配的项
        if (!compareExtensions(this->listWidgets.at(index))) {
            return;
        }

        // 取出存在的项
        currentExtension = this->listWidgets.at(index);
        auto widget = currentExtension->pluginWidget();
        widget->setParent(ui->centralwidget);

        // 即将显示的新窗口大小
        showWidget(widget);
        ui->centralwidget->layout()->setAlignment(widget, Qt::AlignmentFlag::AlignHCenter);

        // 在切换时可能需要调整位置
        if (currentExtension->pluginShowResetPosistion()) {
            ScreenUtil::moveCenterMiddleUp(*this);
        }

        qDebug() << __FUNCTION__ << "index:" << index;
        qDebug() << __FUNCTION__ << "this->x()      =" << this->x();
        qDebug() << __FUNCTION__ << "this->y()      =" << this->y();
        qDebug() << __FUNCTION__ << "this->pos()    =" << this->pos();
        qDebug() << __FUNCTION__ << "this->width()  =" << this->width();
        qDebug() << __FUNCTION__ << "this->height() =" << this->height();
        qDebug() << __FUNCTION__ << "this->minimumSize() =" << this->minimumSize();
        qDebug() << __FUNCTION__ << "currentExtension->pluginWidget()->minimumSize() =" << currentExtension->pluginWidget()->minimumSize();
        qDebug() << "-----------------------------------------------------";
    });

    connect(&ZTBoxPluginLoader::instance(), &ZTBoxPluginLoader::pluginLoadedSignal, [=](){
        foreach (auto var, ZTBoxPluginLoader::instance().plugins()) {
            if (!listWidgets.contains(var)) {
                listWidgets.append(var);
            }
        }
        initPluginCompleter();
    });

    connect(&ZTBoxPluginLoader::instance(), &ZTBoxPluginLoader::pluginsChanged, [=](ZTBoxInterface* plugin){
        if (!listWidgets.contains(plugin)) {
            listWidgets.append(plugin);
        }
        initPluginCompleter();
    });

    connect(&ZTBoxPluginLoader::instance(), &ZTBoxPluginLoader::pluginSwitchSignal, [=](const QString &filePath){
        listWidgets.clear();

        ZTBoxInterface* extension = ZTBoxPluginLoader::instance().loadPluginFile(filePath, true);
        if (extension) {
            listWidgets.append(extension);
            ui->toolslist->addItem(extension->PluginName());
            ui->toolslist->setCurrentText(extension->PluginName());
        } else {
            // ui->toolslist->setPlaceholderText("此插件加载异常");
        }
        initPluginCompleter();
    });

    // 准备 Builtin 的 Widget
#ifdef ZTBOX_BUILTIN_PLUGINS
    listWidgets.append(new HelloExtension);
    listWidgets.append(new SettingsExtension);
    listWidgets.append(new VersionExtension);
    listWidgets.append(new UiAnalyzerPlugin);
    listWidgets.append(new AptHistoryPlugin);
    listWidgets.append(new WindowPosPlugin);
#endif
    // initPluginCompleter
    // initPluginCompleter();
    
#ifdef  QT_DEBUG
    ZTBoxPluginLoader::instance().pluginLoader("plugins");
#else
    #ifdef  Q_OS_LINUX
        ZTBoxPluginLoader::instance().pluginLoader("/usr/lib/zToolsBox/plugins");
    #endif  //Q_OS_LINUX
    ZTBoxPluginLoader::instance().pluginLoader();
#endif  //QT_DEBUG


    // 这是一个无边框的程序
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);

    // 这是一个透明的窗口，由样式表处理窗口圆角
    setAttribute(Qt::WA_TranslucentBackground);

    ui->centralwidget->layout()->setAlignment(ui->frame, Qt::AlignmentFlag::AlignTop);

//    ui->centralwidget->setStyleSheet("QWidget {border: 1px solid red;}");
}

MainWindow::~MainWindow()
{
	
}

// 双击面板时显示或隐藏
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton && currentExtension) {
        
        // 1.反向设置面板的显隐
        ui->frame->setHidden(!ui->frame->isHidden());
        
        // 2.在显隐状态过程中改变更改窗口的大小
        if (ui->frame->isHidden()) {
            resize(size() - QSize(0, 48));
            resize(currentExtension->pluginWidget()->size() + QSize(6, 12));
        } else {
//            resize(currentExtension->pluginWidget()->size());
            resize(size() + QSize(0, 48));
        }

        qDebug() << "currentExtension->pluginWidget()" << currentExtension->pluginWidget()->contentsMargins();

        // 3.对于固定面板控件进行隐关显启
        ui->frame->setEnabled(!ui->frame->isHidden());

        // 4.在进行显启后，定位到固定面板的输入中
        if (ui->frame->isEnabled()) {
            ui->toolslist->setFocus();
        }
    }
}

// 在按下 Esc 键时关闭窗口
void MainWindow::keyPressEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Escape) {
        close();
    }

    if (event->key() == Qt::Key_Control) {

    }
}
